
package com.yadong.smarthome2.datastore;

import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

import com.yadong.smarthome2.datastore.Tables.Argument;
import com.yadong.smarthome2.datastore.Tables.Device;
import com.yadong.smarthome2.datastore.Tables.Function;
import com.yadong.smarthome2.datastore.Tables.Rule;
import com.yadong.smarthome2.datastore.Tables.Status;
import com.yadong.smarthome2.protocol2.ALog;

public class SmartHomeProvider extends ContentProvider {
    private static final int DEVICE = 1;
    private static final int FUNCTION = 2;
    private static final int ARGUMENT = 3;
    private static final int STATUS = 4;
    private static final int RULE = 5;
    public static final String AUTHORITY = "smart_home";

    private SmartHomeDbHelper mDbHelper;
    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    static {
        sURIMatcher.addURI(AUTHORITY, Device.TABLE_NAME, DEVICE);
        sURIMatcher.addURI(AUTHORITY, Function.TABLE_NAME, FUNCTION);
        sURIMatcher.addURI(AUTHORITY, Argument.TABLE_NAME, ARGUMENT);
        sURIMatcher.addURI(AUTHORITY, Status.TABLE_NAME, STATUS);
        sURIMatcher.addURI(AUTHORITY, Rule.TABLE_NAME, RULE);
    }

    @Override
    public boolean onCreate() {
        mDbHelper = new SmartHomeDbHelper(getContext());
        return true;
    }

    @Override
    public int delete(Uri uri, String where, String[] whereArgs) {
        final int match = sURIMatcher.match(uri);
        final SQLiteDatabase db = mDbHelper.getWritableDatabase();
        int out = -1;
        switch (match) {
            case DEVICE: {
                db.beginTransaction();
                Cursor cursor = null;
                Cursor functionCursor = null;
                try {
                    cursor = db.query(Tables.Device.TABLE_NAME,
                            new String[] {
                                Tables.Device.ID
                            },
                            where, whereArgs, null, null, null);
                    if (cursor != null && cursor.moveToFirst()) {
                        long id = cursor.getInt(0);
                        out = (int) id;
                        functionCursor = db.query(Tables.Function.TABLE_NAME,
                                new String[] {
                                    Tables.Function.ID
                                }, Tables.Function.DEVICE_ID + "=?",
                                new String[] {
                                    id + ""
                                }, null, null, null);
                        while (functionCursor != null && functionCursor.moveToNext()) {
                            long functionId = functionCursor.getLong(0);
                            db.delete(Tables.Argument.TABLE_NAME,
                                    Tables.Argument.FUNCTION_ID + "=?", new String[] {
                                        functionId + ""
                                    });
                        }
                        db.delete(Tables.Function.TABLE_NAME,
                                Tables.Function.DEVICE_ID + "=?", new String[] {
                                    id + ""
                                });
                        db.delete(Tables.Status.TABLE_NAME,
                                Tables.Status.DEVICE_ID + "=?", new String[] {
                                    id + ""
                                });
                        db.delete(Tables.Device.TABLE_NAME, Tables.Device.ID + "=?",
                                new String[] {
                                    id + ""
                                });
                        db.setTransactionSuccessful();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (cursor != null)
                        cursor.close();
                    if (functionCursor != null)
                        functionCursor.close();
                    db.endTransaction();
                }
                break;
            }
            case FUNCTION: {
                db.beginTransaction();
                Cursor functionCursor = null;
                try {
                    functionCursor = db.query(Tables.Function.TABLE_NAME,
                            new String[] {
                                Tables.Function.ID
                            }, where,
                            whereArgs, null, null, null);
                    while (functionCursor != null && functionCursor.moveToNext()) {
                        long functionId = functionCursor.getLong(0);
                        db.delete(Tables.Argument.TABLE_NAME,
                                Tables.Argument.FUNCTION_ID + "=?", new String[] {
                                    functionId + ""
                                });
                    }
                    out = db.delete(Tables.Function.TABLE_NAME, where, whereArgs);
                    db.setTransactionSuccessful();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (functionCursor != null) {
                        functionCursor.close();
                    }
                    db.endTransaction();
                }
                break;
            }
            case ARGUMENT:
                out = db.delete(Tables.Argument.TABLE_NAME, where, whereArgs);
                break;
            case STATUS:
                out = db.delete(Tables.Status.TABLE_NAME, where, whereArgs);
                break;
            case RULE:
                out = db.delete(Tables.Rule.TABLE_NAME, where, whereArgs);
                break;
        }
        return out;
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        final int match = sURIMatcher.match(uri);
        final SQLiteDatabase db = mDbHelper.getWritableDatabase();
        long id = -1;
        Uri.Builder builder = new Uri.Builder();
        builder.authority(AUTHORITY);
        switch (match) {
            case DEVICE:
                id = db.insert(Tables.Device.TABLE_NAME, null, values);
                builder.appendPath(Device.TABLE_NAME);
                break;
            case FUNCTION:
                id = db.insert(Tables.Function.TABLE_NAME, null, values);
                builder.appendPath(Function.TABLE_NAME);
                break;
            case ARGUMENT:
                id = db.insert(Tables.Argument.TABLE_NAME, null, values);
                builder.appendPath(Argument.TABLE_NAME);
                break;
            case STATUS:
                id = db.insert(Tables.Status.TABLE_NAME, null, values);
                builder.appendPath(Status.TABLE_NAME);
                break;
            case RULE:
                id = db.insert(Tables.Rule.TABLE_NAME, null, values);
                builder.appendPath(Rule.TABLE_NAME);
        }
        builder.appendPath(id+"");
        return builder.build();
    }

    @Override
    public Cursor query(Uri uri, String[] projects, String selection,
            String[] selectionArgs, String sortOrder) {
        final int match = sURIMatcher.match(uri);
        final SQLiteDatabase db = mDbHelper.getReadableDatabase();
        Cursor out = null;
        switch (match) {
            case DEVICE:
                out = db.query(Tables.Device.TABLE_NAME, projects, selection,
                        selectionArgs, null, null, sortOrder);
                break;
            case FUNCTION:
                out = db.query(Tables.Function.TABLE_NAME, projects, selection,
                        selectionArgs, null, null, sortOrder);
                break;
            case ARGUMENT:
                out = db.query(Tables.Argument.TABLE_NAME, projects, selection,
                        selectionArgs, null, null, sortOrder);
                break;
            case STATUS:
                out = db.query(Tables.Status.TABLE_NAME, projects, selection,
                        selectionArgs, null, null, sortOrder);
                break;
            case RULE:
                out = db.query(Tables.Rule.TABLE_NAME, projects, selection,
                        selectionArgs, null, null, sortOrder);
                break;
            default:
                ALog.loge(SmartHomeProvider.this, "no match for uri:" + uri);
                break;
        }
        return out;
    }

    @Override
    public int update(Uri uri, ContentValues contentValues, String where, String[] whereArgs) {
        final int match = sURIMatcher.match(uri);
        final SQLiteDatabase db = mDbHelper.getReadableDatabase();
        int out = -1;
        switch (match) {
            case DEVICE:
                out = db.update(Tables.Device.TABLE_NAME, contentValues, where,
                        whereArgs);
                break;
            case FUNCTION:
                out = db.update(Tables.Device.TABLE_NAME, contentValues, where,
                        whereArgs);
                break;
            case ARGUMENT:
                out = db.update(Tables.Device.TABLE_NAME, contentValues, where,
                        whereArgs);
                break;
            case STATUS:
                out = db.update(Tables.Device.TABLE_NAME, contentValues, where,
                        whereArgs);
                break;
            case RULE:
                out = db.update(Tables.Rule.TABLE_NAME, contentValues, where,
                        whereArgs);
                break;
            default:
                ALog.loge(SmartHomeProvider.this, "no match for uri:" + uri);
                break;
        }
        return out;
    }

}
